package com.n5x.controller;

import com.n5x.common.base.JsonModel;
import com.n5x.common.base.ResponseCode;
import com.n5x.common.base.TokenModel;
import com.n5x.common.util.StringUtil;
import com.n5x.common.weixinutils.WxPayUtil;
import com.n5x.model.shopping.ShoppingOrder;
import com.n5x.model.shopping.ShoppingOrderDetails;
import com.n5x.model.user.UserInfo;
import com.n5x.model.user.UserTransactionRecord;
import com.n5x.service.IShoppingService;
import com.n5x.service.IUserService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 页面地址跳转Controller
 */
@Controller
public class PayController extends BaseController {
    @Autowired
    private IShoppingService iShoppingService;
    @Autowired
    private IUserService iUserService;

    //支付接口
    @ResponseBody
    @RequestMapping(value = "/doPay", method = {RequestMethod.POST, RequestMethod.GET})
    public JsonModel doPay(Model model, HttpServletRequest request) {
        JsonModel jsonModel = new JsonModel();
        //网页授权后获取传递的参数
        String moneystr = request.getParameter("money");//分为单位
        String openId = request.getParameter("openId");
        String orderId = request.getParameter("orderId");
        String type = request.getParameter("type");
        String token = request.getParameter("token");
        String method = request.getParameter("method");
        WxPayUtil.PayMethod paymethod = WxPayUtil.PayMethod.充值;
        String userId = null;
        try {
            if (!StringUtil.isBlank(token)) {
                TokenModel tm = getTokenModelByToken(token);
                if (null != tm) userId = tm.getUserId();
            }
            if (StringUtil.isBlank(method) || method.equals(WxPayUtil.PayMethod.充值.getMethod()))
                paymethod = WxPayUtil.PayMethod.充值;
            else if (method.equals(WxPayUtil.PayMethod.消费.getMethod())) paymethod = WxPayUtil.PayMethod.消费;
            if (StringUtil.isBlank(moneystr)) return getResultError(ResponseCode.Common_ParamError, "金额不能为空");
            if (StringUtil.isBlank(type)) type = "weixin";
            if (type.equals("weixin")) {
                if (StringUtil.isBlank(openId)) return getResultError(ResponseCode.Common_ParamError, "openId不能为空");
            }
            UserTransactionRecord.TransactionType transactionType = UserTransactionRecord.TransactionType.充值;
            if (!StringUtil.isBlank(orderId)) transactionType = UserTransactionRecord.TransactionType.消费;

            double money = Double.parseDouble(moneystr);
            //测试的时候不加成
            String weixinMoney = new java.text.DecimalFormat("#").format(money * 100);
//            String weixinMoney = moneystr;
            //如果order不为空则进行对单
            if (!StringUtil.isBlank(orderId)) {

                Map pararm = new HashMap();
                pararm.put("id", orderId);
                List<ShoppingOrder> orderlist = iShoppingService.selectUserShopingOrder(pararm);

                if (!CollectionUtils.isEmpty(orderlist)) {
                    ShoppingOrder shoppingOrder = orderlist.get(0);
                    BigDecimal total = new BigDecimal(0);
                    for (ShoppingOrderDetails orderDetails : shoppingOrder.getDetails()) {
                        BigDecimal price = orderDetails.getPrice();
                        BigDecimal qty = new BigDecimal(orderDetails.getQty());

                        BigDecimal all = price.multiply(qty);
                        total = total.add(all);
                    }
                    //0自提 1送货上门
                    String isSend = shoppingOrder.getIsSendToHome() == null ? "1" : shoppingOrder.getIsSendToHome();
                    if (isSend.contains("1")) {
                        total = total.add(new BigDecimal(7));
                    }

                    //金额不符
                    BigDecimal praramTotal = new BigDecimal(moneystr);
                    boolean isTotal = total.compareTo(praramTotal) == 0;
                    if (!isTotal) {
                        return getResultError(ResponseCode.Common_Error, "订单异常");
                    }
                    ;
                } else {
                    return getResultError(ResponseCode.Common_Error, "无此订单");
                }
            }

            String orderOutId = String.valueOf((int) ((Math.random() * 9 + 1) * 1000)) + new Date().getTime();
            //测试金额1分钱
//            weixinMoney = "1";

            String respXml = WxPayUtil.unifiedOrder("菜菜帮下单", orderOutId, weixinMoney, super.getIpAddr(request), openId, type, paymethod);
            logger.info("[weiXinPayResult]resXML:{}", new Object[]{respXml});
            if (respXml.contains("prepay_id")) {
                //保存id
                UserTransactionRecord userTransactionRecord = new UserTransactionRecord(userId, orderOutId, UserTransactionRecord.Method.微信, transactionType, new BigDecimal(moneystr));
                if (!StringUtil.isBlank(orderId)) userTransactionRecord.setNote(orderId);
                String utId = iUserService.saveUserTransactionRecord(userTransactionRecord, null, null);
                Map res = WxPayUtil.getPayMap(respXml);
                res.put("transactionId", utId);//交易流水单号
                res.put("orderOutId", orderOutId);//微信账单
                return getResult(res);
            } else {
                return getResultError(ResponseCode.Common_Error, respXml);
            }


        } catch (Exception e) {
            getResultError(e.toString());
        }

        return jsonModel;
    }

    @ResponseBody
    @RequestMapping(value = "/queryPay", method = {RequestMethod.POST, RequestMethod.GET})
    public JsonModel queryPay(Model model, HttpServletRequest request) {
        String order_no = request.getParameter("order_no");

        if (StringUtils.isBlank(order_no)) return getResultError(ResponseCode.Common_Error, "交易id不能为空");
        try {
            Map resMap = WxPayUtil.queryOrder(order_no);
            return getResult(resMap);
        } catch (IOException e) {
            e.printStackTrace();
            return getResultError(ResponseCode.Common_Error, "查无订单");
        }
    }

    //充值确认
    @ResponseBody
    @RequestMapping(value = "/pay/chargeUpdate")
    public JsonModel updateTransactionRecord() {
        try {
            InputStream inStream = request.getInputStream();


            ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }
            outSteam.close();
            inStream.close();
            String result = new String(outSteam.toByteArray(), "utf-8");// 获取微信调用我们notify_url的返回信息
//            logger.info("[微信回调:{}", new Object[]{result});

            String returnCode = WxPayUtil.getXmlPara(result, "return_code");
            String outTradeNo = WxPayUtil.getXmlPara(result, "out_trade_no");
            logger.info("[微信充值]outTradeNo:{},returnCode:{}", new Object[]{outTradeNo, returnCode});
            if (returnCode.equals(WxPayUtil.PayState.支付成功.getState())) {
                //支付成功
                UserTransactionRecord userTransactionRecord = iUserService.findUserTransactionRecordByTradeNo(outTradeNo);
                if (userTransactionRecord == null) {
                    logger.error("[微信充值失败,交易记录不存在]outTradeNo:{}", new Object[]{outTradeNo});
                    return getResultError(ResponseCode.Common_ParamError, "交易记录不存在");
                }
                if (userTransactionRecord.getDisable() == false) {
                    ///logger.info("[微信充值失败,交易记录已处理]outTradeNo:{}", new Object[]{outTradeNo});
                    return getResult(userTransactionRecord.getId());
                }
                UserTransactionRecord extUserTransactionRecord = null;
                BigDecimal money = userTransactionRecord.getMoney();
                String userId = userTransactionRecord.getFkUser();
                if (money.compareTo(new BigDecimal(1000)) == 0) {
                    //充1000送100
                    money = money.add(new BigDecimal(100));
                    extUserTransactionRecord = new UserTransactionRecord(userId, userTransactionRecord.getTransactionNumber(), UserTransactionRecord.Method.微信, UserTransactionRecord.TransactionType.赠送, new BigDecimal(100));
                    extUserTransactionRecord.setDisable(Boolean.FALSE);
                } else if (money.compareTo(new BigDecimal(500)) == 0) {
                    //充500送20
                    money = money.add(new BigDecimal(20));
                    extUserTransactionRecord = new UserTransactionRecord(userId, userTransactionRecord.getTransactionNumber(), UserTransactionRecord.Method.微信, UserTransactionRecord.TransactionType.赠送, new BigDecimal(20));
                    extUserTransactionRecord.setDisable(Boolean.FALSE);
                } else if (money.compareTo(new BigDecimal(300)) == 0) {
                    //充300送5
                    money = money.add(new BigDecimal(5));
                    extUserTransactionRecord = new UserTransactionRecord(userId, userTransactionRecord.getTransactionNumber(), UserTransactionRecord.Method.微信, UserTransactionRecord.TransactionType.赠送, new BigDecimal(5));
                    extUserTransactionRecord.setDisable(Boolean.FALSE);
                }
                userTransactionRecord.setDisable(Boolean.FALSE);
                UserInfo userInfo = iUserService.findUserInfo(userId);
                logger.info("[微信充值]用户电话:{},用户原金额:{},充值金额:{},交易号:{}", new Object[]{userInfo.getPhone(), userInfo.getBalance(), money, outTradeNo});
                userInfo.setFkLevel("1");
                userInfo.setBalance(userInfo.getBalance().add(money));
                iUserService.saveUserTransactionRecord(userTransactionRecord, userInfo, extUserTransactionRecord);
                logger.info("[微信充值成功]UserTransactionRecord:{}", new Object[]{userTransactionRecord.getId()});
                return getResult(userTransactionRecord.getId());
            }
            logger.error("[微信充值失败]outTradeNo:{},returnCode:{}", new Object[]{outTradeNo, returnCode});
            return getResultError(ResponseCode.Common_Fail, "微信充值失败");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("[微信充值异常]msg:{}", new Object[]{e.getMessage()});
            return getResultError(e.getMessage());
        }
    }


    //消费确认
    @ResponseBody
    @RequestMapping(value = "/pay/payUpdate")
    public JsonModel updatePayRecord() {
        try {
            InputStream inStream = request.getInputStream();
            ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }
            outSteam.close();
            inStream.close();
            String result = new String(outSteam.toByteArray(), "utf-8");// 获取微信调用我们notify_url的返回信息
//            logger.info("[微信回调:{}", new Object[]{result});

            String returnCode = WxPayUtil.getXmlPara(result, "return_code");
            String outTradeNo = WxPayUtil.getXmlPara(result, "out_trade_no");
            logger.info("[微信消费]:outTradeNo:{},returnCode:{}", new Object[]{outTradeNo, returnCode});
            if (returnCode.equals(WxPayUtil.PayState.支付成功.getState())) {
                //支付成功
                UserTransactionRecord userTransactionRecord = iUserService.findUserTransactionRecordByTradeNo(outTradeNo);
                if (userTransactionRecord == null) {
                    logger.error("[微信消费失败,交易记录不存在]outTradeNo:{}", outTradeNo);
                    return getResultError(ResponseCode.Common_ParamError, "交易记录不存在");
                }
                String orderId = userTransactionRecord.getNote();
                if (StringUtils.isBlank(orderId)) {
                    logger.error("[微信消费失败,订单不存在1]:orderId:{}", new Object[]{orderId});
                    return getResultError(ResponseCode.Common_ParamError, "订单ID不能为空");
                }
                if (userTransactionRecord.getDisable() == false) {
                    //logger.error("[微信消费失败,交易记录已处理]outTradeNo:{}",outTradeNo);
                    return getResult(orderId);
                }
                String redisKey = "pay_" + orderId;
                ShoppingOrder shoppingOrder = iShoppingService.findShoppingOrder(orderId);
                if (shoppingOrder == null) {
                    logger.error("[微信消费失败,订单不存在2]:orderId:{}", new Object[]{orderId});
                    return getResultError(ResponseCode.Common_ParamError, "订单不存在");
                }
                shoppingOrder.setTotalMoney(userTransactionRecord.getMoney());
                shoppingOrder.setTransactionMethod(ShoppingOrder.TransactionMethod.微信.getMethod());
                shoppingOrder.setTransactionNumber(userTransactionRecord.getId());
                logger.info("[微信消费]:shoppingOrderId:{},totalMoney:{},transactionMethod:{},transactionNumber:{},userTransactionRecord:{}",
                        new Object[]{shoppingOrder.getId(), shoppingOrder.getTotalMoney(), shoppingOrder.getTransactionMethod(), shoppingOrder.getTransactionNumber(), userTransactionRecord.getTransactionNumber()});
                Map<String, Object> resultMap = iShoppingService.saveShoppingOrderByPay(shoppingOrder, userTransactionRecord.getFkUser());
                logger.info("[微信消费结果]:shoppingOrder:{},outTradeNo:{},resultMap:{}", new Object[]{shoppingOrder.getId(), outTradeNo, resultMap});
                if (resultMap != null && !resultMap.isEmpty()) {
                    String key = resultMap.keySet().iterator().next();
                    logger.error("[微信消费失败]:shoppingOrder:{},outTradeNo:{},resultMap:{}", new Object[]{shoppingOrder.getId(), outTradeNo, resultMap});
                    return getResultError(key, (String) resultMap.get(key));
                }
                redisCache.setCacheObject(redisKey, orderId, 10);
                return getResult(shoppingOrder.getId());
            }
            logger.error("[微信消费失败]:outTradeNo:{},returnCode:{}", new Object[]{outTradeNo, returnCode});
            return getResultError(ResponseCode.Common_Fail, "微信消费失败");
        } catch (Exception e) {
            logger.error("[微信消费异常:{}", e.getMessage());
            e.printStackTrace();
            return getResultError(e.getMessage());
        }
    }
}